home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / bin / btmakemetafile.bittorrent < prev    next >
Encoding:
Text File  |  2007-02-19  |  4.5 KB  |  158 lines

  1. #! /usr/bin/python
  2.  
  3. # Written by Bram Cohen
  4. # see LICENSE.txt for license information
  5.  
  6. from sys import argv
  7. from os.path import getsize, split, join, abspath, isdir
  8. from os import listdir
  9. from sha import sha
  10. from copy import copy
  11. from string import strip
  12. from BitTorrent.bencode import bencode
  13. from BitTorrent.btformats import check_info
  14. from BitTorrent.parseargs import parseargs, formatDefinitions
  15. from threading import Event
  16. from time import time
  17.  
  18. defaults = [
  19.     ('piece_size_pow2', 18,
  20.         "which power of 2 to set the piece size to"),
  21.     ('comment', '',
  22.         "optional human-readable comment to put in .torrent"),
  23.     ('target', '',
  24.         "optional target file for the torrent")
  25.     ]
  26.  
  27. ignore = ['core', 'CVS']
  28.  
  29. def dummy(v):
  30.     pass
  31.  
  32. def make_meta_file(file, url, piece_len_exp = 18, 
  33.         flag = Event(), progress = dummy, progress_percent=1, comment = None, target = None):
  34.     if piece_len_exp == None:
  35.         piece_len_exp = 18
  36.     piece_length = 2 ** piece_len_exp
  37.     a, b = split(file)
  38.     if not target:
  39.         if b == '':
  40.             f = a + '.torrent'
  41.         else:
  42.             f = join(a, b + '.torrent')
  43.     else:
  44.         f = target
  45.     info = makeinfo(file, piece_length, flag, progress, progress_percent)
  46.     if flag.isSet():
  47.         return
  48.     check_info(info)
  49.     h = open(f, 'wb')
  50.     data = {'info': info, 'announce': strip(url), 'creation date': long(time())}
  51.     if comment:
  52.         data['comment'] = comment
  53.     h.write(bencode(data))
  54.     h.close()
  55.  
  56. def calcsize(file):
  57.     if not isdir(file):
  58.         return getsize(file)
  59.     total = 0
  60.     for s in subfiles(abspath(file)):
  61.         total += getsize(s[1])
  62.     return total
  63.  
  64. def makeinfo(file, piece_length, flag, progress, progress_percent=1):
  65.     file = abspath(file)
  66.     if isdir(file):
  67.         subs = subfiles(file)
  68.         subs.sort()
  69.         pieces = []
  70.         sh = sha()
  71.         done = 0
  72.         fs = []
  73.         totalsize = 0.0
  74.         totalhashed = 0
  75.         for p, f in subs:
  76.             totalsize += getsize(f)
  77.  
  78.         for p, f in subs:
  79.             pos = 0
  80.             size = getsize(f)
  81.             fs.append({'length': size, 'path': p})
  82.             h = open(f, 'rb')
  83.             while pos < size:
  84.                 a = min(size - pos, piece_length - done)
  85.                 sh.update(h.read(a))
  86.                 if flag.isSet():
  87.                     return
  88.                 done += a
  89.                 pos += a
  90.                 totalhashed += a
  91.                 
  92.                 if done == piece_length:
  93.                     pieces.append(sh.digest())
  94.                     done = 0
  95.                     sh = sha()
  96.                 if progress_percent:
  97.                     progress(totalhashed / totalsize)
  98.                 else:
  99.                     progress(a)
  100.             h.close()
  101.         if done > 0:
  102.             pieces.append(sh.digest())
  103.         return {'pieces': ''.join(pieces),
  104.             'piece length': piece_length, 'files': fs, 
  105.             'name': split(file)[1]}
  106.     else:
  107.         size = getsize(file)
  108.         pieces = []
  109.         p = 0
  110.         h = open(file, 'rb')
  111.         while p < size:
  112.             x = h.read(min(piece_length, size - p))
  113.             if flag.isSet():
  114.                 return
  115.             pieces.append(sha(x).digest())
  116.             p += piece_length
  117.             if p > size:
  118.                 p = size
  119.             if progress_percent:
  120.                 progress(float(p) / size)
  121.             else:
  122.                 progress(min(piece_length, size - p))
  123.         h.close()
  124.         return {'pieces': ''.join(pieces), 
  125.             'piece length': piece_length, 'length': size, 
  126.             'name': split(file)[1]}
  127.  
  128. def subfiles(d):
  129.     r = []
  130.     stack = [([], d)]
  131.     while len(stack) > 0:
  132.         p, n = stack.pop()
  133.         if isdir(n):
  134.             for s in listdir(n):
  135.                 if s not in ignore and s[:1] != '.':
  136.                     stack.append((copy(p) + [s], join(n, s)))
  137.         else:
  138.             r.append((p, n))
  139.     return r
  140.  
  141. def prog(amount):
  142.     print '%.1f%% complete\r' % (amount * 100),
  143.  
  144. if __name__ == '__main__':
  145.     if len(argv) < 3:
  146.         print 'usage is -'
  147.         print argv[0] + ' file trackerurl [params]'
  148.         print
  149.         print formatDefinitions(defaults, 80)
  150.     else:
  151.         try:
  152.             config, args = parseargs(argv[3:], defaults, 0, 0)
  153.             make_meta_file(argv[1], argv[2], config['piece_size_pow2'], progress = prog,
  154.                 comment = config['comment'], target = config['target'])
  155.         except ValueError, e:
  156.             print 'error: ' + str(e)
  157.             print 'run with no args for parameter explanations'
  158.